<?xml version="1.0" encoding="iso-8859-1"?>
<!DOCTYPE html 
     PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
     "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
  <title>File: README</title>
  <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
  <meta http-equiv="Content-Script-Type" content="text/javascript" />
  <link rel="stylesheet" href=".././rdoc-style.css" type="text/css" media="screen" />
  <script type="text/javascript">
  // <![CDATA[

  function popupCode( url ) {
    window.open(url, "Code", "resizable=yes,scrollbars=yes,toolbar=no,status=no,height=150,width=400")
  }

  function toggleCode( id ) {
    if ( document.getElementById )
      elem = document.getElementById( id );
    else if ( document.all )
      elem = eval( "document.all." + id );
    else
      return false;

    elemStyle = elem.style;
    
    if ( elemStyle.display != "block" ) {
      elemStyle.display = "block"
    } else {
      elemStyle.display = "none"
    }

    return true;
  }
  
  // Make codeblocks hidden by default
  document.writeln( "<style type=\"text/css\">div.method-source-code { display: none }</style>" )
  
  // ]]>
  </script>

</head>
<body>



  <div id="fileHeader">
    <h1>README</h1>
    <table class="header-table">
    <tr class="top-aligned-row">
      <td><strong>Path:</strong></td>
      <td>README
      </td>
    </tr>
    <tr class="top-aligned-row">
      <td><strong>Last Update:</strong></td>
      <td>Wed Aug 16 00:35:57 EDT 2006</td>
    </tr>
    </table>
  </div>
  <!-- banner header -->

  <div id="bodyContent">



  <div id="contextContent">

    <div id="description">
      <h1>ActiveTest</h1>
<h2>Cautionary Word</h2>
<p>
ACTIVETEST IS NOT FINISHED. IT IS MISSING A LOT OF FEATURES. MUCH IS
SUBJECT TO CHANGE.
</p>
<h2>Contents</h2>
<h3>Modules and Classes</h3>
<p>
<a href="../classes/ActiveTest/Base.html">ActiveTest::Base</a> - wraps
Test::Unit::TestCase non-invasively, allows setup/teardown to be nested
</p>
<p>
<a href="../classes/ActiveTest/Subject.html">ActiveTest::Subject</a> -
abstract class for test case types, like Controller and Model.
</p>
<p>
<a href="../classes/ActiveTest/Controller.html">ActiveTest::Controller</a>
- subject for testing controllers, providing dynamic methods and asserts
</p>
<p>
<a
href="../classes/ActiveTest/Asserts/Assigns.html">ActiveTest::Asserts::Assigns</a>
- methods for asserting template variable assignments
</p>
<p>
<a
href="../classes/ActiveTest/Asserts/Authentication.html">ActiveTest::Asserts::Authentication</a>
- class method for requiring login; login/logout; assertions
</p>
<p>
<a
href="../classes/ActiveTest/Asserts/Authorisation.html">ActiveTest::Asserts::Authorisation</a>
- class method for requiring permissions; assertions
</p>
<p>
<a
href="../classes/ActiveTest/Asserts/Difference.html">ActiveTest::Asserts::Difference</a>
- methods for asserting difference and change for return values
</p>
<p>
<a
href="../classes/ActiveTest/Asserts/Validations.html">ActiveTest::Asserts::Validations</a>
- methods for asserting ActiveRecord errors
</p>
<h3>Other</h3>
<p>
active_test.rb - load up ActiveTest
</p>
<p>
active_test/filter.rb - the one and only monkey patch: filter out anything
in the ActiveTest module
</p>
<h2>Foreword</h2>
<p>
I would first like to precede anything with a quick reason why you should
test. Testing is, contrary to popular belief, about <b>design</b>. It is
not about stamping out bugs. Bugs are the result of bad designs or bad
implementations of design. It is in the grey area between the two that
makes testing seem more like a mosquito repellent. Tests, like the code
they are &#8216;documenting&#8217; or &#8216;specifying&#8217; or
&#8216;testing&#8217;, are just as prone to bad design or implementation.
</p>
<p>
Rather than come up with some grandiose redefinition of tests, why not just
make them easier to write? That should deal with <b>most</b> cases of bad
design or implementation.
</p>
<h2>About Similarities</h2>
<p>
While other implementations are attempting, with various success, to extend
the functionality of <a href="../classes/Test/Unit.html">Test::Unit</a> and
make it more Rails friendly, they have their own unique ways of setting up
and developing tests. The price of their uniqueness is that they move away
from the traditional thinking of a Rails developer. They introduce more
complications of design and elements to be aware of, meaning more time to
understand how something can be done. We should not have to think about the
nuances of a test suite and model, how they relate or how to design our
application within its specific language. The closer model and test are to
each other in design and usage, the easier it is to design them rapidly.
That is why you will see a lot of similarities between ActiveTest and its
paronymic relative, ActiveRecord.
</p>
<h2>Description</h2>
<p>
ActiveTest wraps <a href="../classes/Test/Unit.html">Test::Unit</a> in a
Rails-like mould. It does a number of things which would be madness to
write for a single project. Here are a few of its features:
</p>
<ul>
<li>protects you from the disasters of monkey patching

</li>
<li>provides a highly extensible, flexible design &#8212; forget
Test::Unit::TestCase

</li>
<li>provides class-level macros, a la ActiveRecord, for standard tests

</li>
<li>provides multiple readable ways of defining tests

</li>
<li>provides instance-level assertions and helper methods

</li>
<li>provides default specifications for all major forms of testing in Rails

</li>
<li>follows Convention over Configuration, allows both

</li>
<li>generally makes testing pleasurable

</li>
</ul>
<p>
If you do nothing more than install ActiveTest and have all your tests
inherit from <a href="../classes/ActiveTest/Base.html">ActiveTest::Base</a>
(not recommended, use a Subject), you will receive a few benefits without
drawbacks:
</p>
<ul>
<li>setup and teardown are nested

</li>
<li>all setups/teardowns are executed without <tt>super</tt>

</li>
<li>classes inheriting from <a
href="../classes/ActiveTest/Base.html">ActiveTest::Base</a> can be
subclassed without detriment

</li>
<li>anything in the namespace of ActiveTest will not be run by <a
href="../classes/Test/Unit.html">Test::Unit</a>

</li>
<li>behaves exactly like Test::Unit::TestCase

</li>
</ul>
<h2>The Design</h2>
<p>
At the heart of ActiveTest is <a
href="../classes/ActiveTest/Base.html">ActiveTest::Base</a> and the filter
addition. The filter prevents anything within the namespace of ActiveTest
to be run by <a
href="../classes/Test/Unit/AutoRunner.html">Test::Unit::AutoRunner</a>. The
Base class itself makes setup and teardown nested, meaning any setup or
teardown defined in classes inheriting from Base will be proc&#8217;d,
stuffed in a stack and executed in the order of definition when setup or
teardown are called. This allows all sorts of nifty things to happen,
namely inheritance.
</p>
<p>
Base is extended by <a
href="../classes/ActiveTest/Subject.html">ActiveTest::Subject</a>, the
abstract class for Subjects. Specific sets of ActiveTest::Asserts are mixed
into each pre-defined Subject, giving a small set of assertions,
convenience methods and macros to use in those subject tests.
</p>
<p>
The instance methods within Subjects and Asserts are helpers for your
tests. The class methods are your metalanguage. If you learn the few
patterns for each Subject, test-driven design will become a breeze.
</p>
<p>
Read on for more specifics.
</p>
<h2>Subjects</h2>
<p>
Subjects are the types of tests you will run, like Controller, Model,
Helper, View, Stress and Integration. Virgin Subjects can be created by
extending the <a
href="../classes/ActiveTest/Subject.html">ActiveTest::Subject</a> class
itself, exactly how one creates new models inheriting from
ActiveRecord::Base. You can, if you wish to have a completely blank slate,
inherit directly from <a
href="../classes/ActiveTest/Base.html">ActiveTest::Base</a> too, but you
will most like use the following formulations:
</p>
<pre>
  class ExampleControllerTest &lt; ActiveTest::Controller
  end
  class ExampleTest &lt; ActiveTest::Model
  end

  etc.
</pre>
<p>
The best way to think of subjects is that they are modeling the Rails
domain. Everyone has a controller, view, helper, or record, so we can make
certain assumptions that, say, ActiveRecord cannot. This is not differing
from the ActiveRecord metaphors &#8212; it is just filling in some blanks
for convenience. If you don&#8217;t like the convenience, just extend <a
href="../classes/ActiveTest/Base.html">ActiveTest::Base</a>. You&#8216;ll
get all the fancy stuff of Test::Unit::TestCase, no less and certainly no
more.
</p>
<h2>Assertions</h2>
<p>
ActiveTest allows you to create &#8216;assertion packages&#8217;. Think
&#8216;Acts As &#8230;&#8217;. ActiveTest comes with a modest set of
assertions. They are enumerated in the contents above. Each of them are
pre-included in one or many Subjects for your immediate use. For example,
all subjects have <a
href="../classes/ActiveTest/Asserts/Difference.html">ActiveTest::Asserts::Difference</a>,
but only <a
href="../classes/ActiveTest/Controller.html">ActiveTest::Controller</a> has
<a
href="../classes/ActiveTest/Asserts/Assigns.html">ActiveTest::Asserts::Assigns</a>.
Becoming familiar with the assertions available to you can dramatically
speed up your testing.
</p>
<h2>Dynamic Methods</h2>
<p>
Each Subject which inherits from <a
href="../classes/ActiveTest/Subject.html">ActiveTest::Subject</a> will have
its own set of dynamic methods which allow you to write tests very quickly
and efficiently. Almost all of them will follow this pattern:
</p>
<pre>
  test_(method)_(test)_(operation) options = {}
</pre>
<p>
For example, in <a
href="../classes/ActiveTest/Controller.html">ActiveTest::Controller</a>
there is the <tt>responds_with</tt> test:
</p>
<pre>
  test_new_responds_with_new_item
</pre>
<p>
This method will automatically define a full test for the &#8216;new&#8217;
action, ensuring that it gives a successful HTTP code, a template and
assigns an instance variable to the template (by default with the most
likely variable name). That turns six lines of code into one. And if you
think that is bad, you should read the caveat to dynamic methods in <a
href="../classes/ActiveTest/Subject.html">ActiveTest::Subject</a>.
</p>
<h2>Example With Comments</h2>
<pre>
  class ArticlesControllerTest &lt; ActiveTest::Controller

    # Each Subject has a setup class method
    setup :login_as =&gt; :quentin

    # ActiveTest::Controller automatically includes Asserts::Authenticated (non-invasive)
    test_require_login_for :edit, :update, :new, :create, :destroy

    # ActiveTest::Controller also has the non-invasive Asserts::Authorisation
    test_require_permission_for :destroy

    # Most dynamic methods default to a convention
    test_should_index_items

    # In ActiveTest::Controller, test_should_* is a synonym for this method:
    test_new_responds_with_new_item

    test_should_show_item :params =&gt; { :id =&gt; 1 }
    test_show_fails_to_show_item :params =&gt; { :id =&gt; 19361 }

    # You can create :before and :after filters around a test
    # Unless noted, procs are in the INSTANCE scope -- not CLASS, where you define them
    test_should_index_items_for_guests :before =&gt; proc { logout }

    # Many options are flexible. Here, you can set params to a method, called during testing:
    test_should_create_item :params =&gt; :a_good_article

    # You can set params to a proc
    test_create_fails_to_create_item :params =&gt; proc { a_good_article.merge(:body =&gt; nil) }

    # Another example, this time directly defining the hash
    test_should_edit_item :params =&gt; proc {{ :id =&gt; articles(:boring_article).id }}

    # Typical situations...
    test_edit_fails_to_edit_item :params =&gt; { :id =&gt; 19361 }

    test_should_update_item :params =&gt; proc { a_good_article.merge(:body =&gt; &quot;flibble&quot;) }
    test_update_fails_to_update_item :params =&gt; { :id =&gt; 19361 }

    # Creating definitions in a more Spec-ish manner:
    test_should_destroy_item do |spec|
      spec.before = proc { login_as :arthur }
      spec.params = proc {{ :id =&gt; articles(:arthurs_article).id }}
      spec.redirect = :articles_url
    end

    # A very Specy test:
    specify &quot;admin should destroy all items, redirect, ensure no more articles&quot; do |spec|
      spec.action = :destroy_all
      spec.method = :delete
      spec.redirect = :articles_url
      spec.operation = :destroy_item
      spec.before = Proc.new do
        login_as :admin
        create_item(:create, a_good_article)
        assert Article.count &gt; 1
      end
      spec.after = Proc.new do
        assert Article.count == 0
      end
    end

    protected
    # return a hash for parameters
    def a_good_article
      return :article =&gt; { :title =&gt; &quot;And now...&quot;, :body =&gt; &quot;for something completely different&quot; }
    end
  end
</pre>
<h2>Extending ActiveTest</h2>
<p>
Now that you&#8217;ve seen everything that ActiveTest is about,
you&#8217;re probably thinking it isn&#8217;t enough. Well, half of this
library is about making it easy to DRY up tests without losing the power to
design and specify. In bringing the concept of modeling to tests, so too
come the powers of extension.
</p>
<p>
Extending ActiveTest is as easy as subclassing and including. It uses the
same design as extending ActiveRecord, meaning you can have plugins for
custom ActiveTest classes, Subjects or Asserts with a minimum of fuss.
</p>
<h3>Extending <a href="../classes/ActiveTest/Base.html">ActiveTest::Base</a> or <a href="../classes/ActiveTest/Subject.html">ActiveTest::Subject</a></h3>
<p>
When you want to extend the behaviour of ActiveTest, work on Base or
Subject. Base is only for situations which will not be directly inherited
for a test case. This is just a matter of design; there is nothing
restricting you from doing otherwise. However, any addition to the way
tests behave beyond the setup/teardown nesting will most likely be added to
Subject, so parallels to <a
href="../classes/ActiveTest/Controller.html">ActiveTest::Controller</a>
ought to inherit from Subject.
</p>
<pre>
  class ActiveTest::Library &lt; ActiveTest::Base
  end

  class ActiveTest::YourSubject &lt; ActiveTest::Subject
  end
  ActiveTest::YourSubject.class_eval do
    # include the relevant assertions here
  end
</pre>
<h3>Extending ActiveTest::Asserts</h3>
<p>
If you want to create a new assertion suite for a particular Subject, all
you need to do is create a plugin with this init.rb:
</p>
<pre>
  begin
    require 'active_test'
    ActiveTest::PickASubject.class_eval do
      include ActiveTest::Asserts::YourAssertions
    end
    # add more relevant subjects here
  rescue LoadError
    puts &quot;Please install ActiveTest to use this plugin&quot;
  end
</pre>
<p>
And in your plugin/lib:
</p>
<pre>
  module ActiveTest
    module Asserts
      module YourAssertion

        def self.included(base)
          base.extend(ClassMethods)
        end

        module ClassMethods
        end

        def instance_method
        end
      end
    end
  end
</pre>
<p>
That all looks very familiar, doesn&#8217;t it?
</p>

    </div>


   </div>


  </div>


    <!-- if includes -->

    <div id="section">





      


    <!-- if method_list -->


  </div>


<div id="validator-badges">
  <p><small><a href="http://validator.w3.org/check/referer">[Validate]</a></small></p>
</div>

</body>
</html>